﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using ParsecClient.Classes;
using ParsecClient.ParsecRaidWebService;
using ParsecParser;
using ParsecParser.Communication;
using ParsecParser.Data;
using ParsecParser.Display;
using ParsecParser.Helpers;

namespace ParsecClient
{
    /// <summary>
    /// Interaction logic for ManageRaidGroups.xaml
    /// </summary>
    public partial class ManageRaidGroups : Window
    {
        public ManageRaidGroups()
        {
            InitializeComponent();
        }

        private void btnDone_Click(object sender, RoutedEventArgs e)
        {

            try
            {
                this.Close();
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", "Error on btnDone_Click", ex, this, true);
                this.Close();
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            //ParsecWindow mw = ((ParsecWindow)Owner);
            lstGroups.ItemsSource = ((App)Application.Current).RaidGroups.Select(x => new ListBoxItem() { Content = x.Name }).ToList();
        }

        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(txtRaidGroupName.Text) || string.IsNullOrEmpty(txtRaidGroupPass.Text))
                {
                    ((App)Application.Current).HandleError("You must provide a Raid Name and Password", null, null, this, false);
                }
                else if (txtRaidGroupName.Text.Length < 4 || txtRaidGroupPass.Text.Length < 4)
                {
                    ((App)Application.Current).HandleError("Raid Name and Password must be 4 characters or more", null, null, this, false);
                }
                else if (!txtRaidGroupName.Text.IsDigitsOrLettersOrSpaces())
                {
                    ((App)Application.Current).HandleError("Raid Name contain digits or letters or spaces and it cannot begin or end with a space", null, null, this, false);
                }
                else if (!txtRaidGroupPass.Text.IsDigitsOrLetters())
                {
                    ((App)Application.Current).HandleError("Raid Password must only contain digits or letters", null, null, this, false);
                }
                else
                {
                    using (ParsecRaidServiceSoapClient service = new ParsecRaidServiceSoapClient())
                    {
                        var keyVal = service.TestConnection(new ParsecRaidParameters() { RaidGroup = txtRaidGroupName.Text, RaidPassword = txtRaidGroupPass.Text });
                        if (string.IsNullOrEmpty(keyVal.ErrorMessage))
                        {
                            RaidGroup r = new RaidGroup() { Name = txtRaidGroupName.Text, Password = txtRaidGroupPass.Text };
                            ((App)Application.Current).RaidGroups.Add(r);
                            if (string.IsNullOrEmpty(((ParsecWindow)Application.Current.MainWindow).CurrentRaidGroup.Name))
                                ((ParsecWindow)Application.Current.MainWindow).CurrentRaidGroup = r;
                            txtRaidGroupName.Text = null;
                            txtRaidGroupPass.Text = null;
                            lstGroups.ItemsSource = ((App)Application.Current).RaidGroups.Select(x => new ListBoxItem() { Content = x.Name }).ToList();
                        }
                        else
                        {
                            ((App)Application.Current).HandleError("Error: " + keyVal.ErrorMessage, null, null, this, false);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", "Error on btnAdd_Click", ex, this, true);
            }
        }

        private void btnCreate_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(txtRaidGroupName.Text) || string.IsNullOrEmpty(txtRaidGroupPass.Text))
                {
                    ((App)Application.Current).HandleError("You must provide a Raid Name and Password", null, null, this, false);
                }
                else if (txtRaidGroupName.Text.Length < 4 || txtRaidGroupPass.Text.Length < 4)
                {
                    ((App)Application.Current).HandleError("Raid Name and Password must be 4 characters or more", null, null, this, true);
                }
                else if (!txtRaidGroupName.Text.IsDigitsOrLettersOrSpaces())
                {
                    ((App)Application.Current).HandleError("Raid Name contain digits or letters or spaces and it cannot begin or end with a space", null, null, this, false);
                }
                else if (!txtRaidGroupPass.Text.IsDigitsOrLetters())
                {
                    ((App)Application.Current).HandleError("Raid Password must only contain digits or letters", null, null, this, false);
                }
                else
                {
                    PasswordWindow pwin = new PasswordWindow("Enter an Admin Password that enables you to delete or modify this group later", CreateGroupAdminPassOk, null);
                    pwin.Owner = this;
                    pwin.ShowDialog();
                }
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", "Error on btnCreate_Click", ex, this, true);
            }
        }

        private void btnRemoveGroup_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty((string)txtCurrentName.Content))
                {
                    if (HandleMessage("Are you sure you want to remove this group from your list?", true))
                    {
                        ((App)Application.Current).RaidGroups.RemoveAll(x => string.Compare(x.Name, (string)txtCurrentName.Content) == 0);
                        if (string.Compare(((ParsecWindow)Application.Current.MainWindow).CurrentRaidGroup.Name, (string)txtCurrentName.Content) == 0)
                            ((ParsecWindow)Application.Current.MainWindow).CurrentRaidGroup = new RaidGroup();
                        var items = ((App)Application.Current).RaidGroups.Select(x => new ListBoxItem() { Content = x.Name }).ToList();
                        lstGroups.SelectedItem = null;
                        lstGroups.ItemsSource = items;
                    }
                }
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", "Error on btnRemoveGroup_Click", ex, this, true);
            }
        }

        private void btnDeleteGroup_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty((string)txtCurrentName.Content))
                {
                    if (HandleMessage("Are you sure you want to remove this group from the server?", true))
                    {
                        //if admin password is not set ask for it
                        if (string.IsNullOrEmpty((string)txtCurrentAdminPassword.Content))
                        {
                            PasswordWindow pwin = new PasswordWindow("Enter the Admin Password used when this group was created", DeletePasswordAdminEnteredOk, null);
                            pwin.Owner = this;
                            pwin.ShowDialog();
                        }
                        else
                        {
                            string m = DeleteRaidGroupFromServer((string)txtCurrentName.Content, (string)txtCurrentPassword.Content, (string)txtCurrentAdminPassword.Content);
                            if (string.IsNullOrEmpty(m))
                            {
                                ((App)Application.Current).RaidGroups.RemoveAll(x => string.Compare(x.Name, (string)txtCurrentName.Content) == 0);
                                if (string.Compare(((ParsecWindow)Application.Current.MainWindow).CurrentRaidGroup.Name, (string)txtCurrentName.Content) == 0)
                                    ((ParsecWindow)Application.Current.MainWindow).CurrentRaidGroup = new RaidGroup();
                                lstGroups.ItemsSource = ((App)Application.Current).RaidGroups.Select(x => new ListBoxItem() { Content = x.Name }).ToList();
                            }
                            else
                            {
                                ((App)Application.Current).HandleError(m, null, null, this, false);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", "Error on btnDeleteGroup_Click", ex, this, true);
            }
        }
        public void DeletePasswordAdminEnteredOk(object sender, PasswordOkEventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(e.Password))
                {
                    ((App)Application.Current).HandleError("You must provide an Admin Password", null, null, this, false);
                }
                else
                {
                    PasswordWindow pwin = (PasswordWindow)sender;
                    string m = DeleteRaidGroupFromServer((string)txtCurrentName.Content, (string)txtCurrentPassword.Content, e.Password);
                    if (string.IsNullOrEmpty(m))
                    {
                        if (string.Compare(((ParsecWindow)Application.Current.MainWindow).CurrentRaidGroup.Name, (string)txtCurrentName.Content) == 0)
                            ((ParsecWindow)Application.Current.MainWindow).CurrentRaidGroup = new RaidGroup();
                        ((App)Application.Current).RaidGroups.RemoveAll(x => string.Compare(x.Name, (string)txtCurrentName.Content) == 0);
                        lstGroups.ItemsSource = ((App)Application.Current).RaidGroups.Select(x => new ListBoxItem() { Content = x.Name }).ToList();
                        pwin.Close();
                    }
                    else
                    {
                        ((App)Application.Current).HandleError(m, null, null, this, false);
                    }
                }
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", "Error on DeletePasswordAdminEnteredOk", ex, this, true);
            }
        }
        public void CreateGroupAdminPassOk(object sender, PasswordOkEventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(e.Password))
                {
                    ((App)Application.Current).HandleError("You must provide an Admin Password", null, null, this, false);
                }
                else if (e.Password.Length < 4)
                {
                    ((App)Application.Current).HandleError("Admin Password must be 4 characters or more", null, null, this, false);
                }
                else if (!e.Password.IsDigitsOrLetters())
                {
                    ((App)Application.Current).HandleError("Admin Password must only contain digits or letters", null, null, this, false);
                }
                else
                {
                    PasswordWindow pwin = (PasswordWindow)sender;
                    using (ParsecRaidServiceSoapClient service = new ParsecRaidServiceSoapClient())
                    {
                        var keyVal = service.RequestRaidGroup(App.GetServicePayload(ParsecRaidServiceHelpers.StringifyServiceCommand(txtRaidGroupName.Text, txtRaidGroupPass.Text, e.Password)));
                        if (keyVal.Success)
                        {
                            RaidGroup r = new RaidGroup() { Name = txtRaidGroupName.Text, Password = txtRaidGroupPass.Text, AdminPassword = e.Password };
                            ((App)Application.Current).RaidGroups.Add(r);
                            if (string.IsNullOrEmpty(((ParsecWindow)Application.Current.MainWindow).CurrentRaidGroup.Name))
                                ((ParsecWindow)Application.Current.MainWindow).CurrentRaidGroup = r;
                            txtRaidGroupName.Text = null;
                            txtRaidGroupPass.Text = null;
                            lstGroups.ItemsSource = ((App)Application.Current).RaidGroups.Select(x => new ListBoxItem() { Content = x.Name }).ToList();
                            pwin.Close();
                            HandleMessage("New Group Created", false);
                        }
                        else
                        {
                            pwin.Close();
                            ((App)Application.Current).HandleError("Group Rejected: " + keyVal.Message, null, null, this, false);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", "Error on CreateGroupAdminPassOk", ex, this, true);
            }
        }
        public bool HandleMessage(string msg, bool showCancel)
        {
            if (!string.IsNullOrEmpty(msg))
            {
                MessageWindow m = new MessageWindow(msg, false, showCancel, true, true);
                m.Owner = this;
                return m.ShowDialog() ?? false;
            }
            return false;
        }

        private void lstGroups_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                txtCurrentName.Content = null;
                txtCurrentPassword.Content = null;
                txtCurrentAdminPassword.Content = null;
                if (lstGroups.SelectedItem != null)
                {
                    string selectedValue = (string)((ListBoxItem)lstGroups.SelectedItem).Content;
                    RaidGroup r = ((App)Application.Current).RaidGroups.FirstOrDefault(x => string.Compare(x.Name, selectedValue) == 0);
                    if (r != null)
                    {
                        txtCurrentName.Content = r.Name;
                        txtCurrentPassword.Content = r.Password;
                        txtCurrentAdminPassword.Content = r.AdminPassword;
                    }
                }

            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", "Error on lstGroups_SelectionChanged", ex, this, true);
            }
        }
        private string DeleteRaidGroupFromServer(string name, string password, string adminPassword)
        {
            using (ParsecRaidServiceSoapClient service = new ParsecRaidServiceSoapClient())
            {
                var r = service.TestConnection(new ParsecRaidParameters() { RaidGroup = name, RaidPassword = password });
                if (!string.IsNullOrEmpty(r.ErrorMessage))
                {
                    return r.ErrorMessage;
                }
                else
                {
                    var d = service.DeleteRaidGroup(App.GetServicePayload(ParsecRaidServiceHelpers.StringifyServiceCommand(name, password, adminPassword)));
                    return d.Message;
                }
            }
        }
    }
}
